package ${package};

import com.common.*;
import com.main.aop.LogAnnotation;
import com.main.dao.platform.CommonDao;
import ${daoPackage}.${className}Dao;
import com.main.pojo.platform.StateInfo;
import ${beanPackage}.${className};
import com.main.pojo.platform.Bridge;
import ${servicePackage}.${className}Service;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 对象服务层实现类
 * @author ${author}
 */
@Service
@Transactional
public class ${className}ServiceImpl implements ${className}Service {
	@Resource
	private ${className}Dao ${paramName}Dao;
<#if autoInitFromAccess == true>
	@Resource
	private CommonDao comDao;
</#if>

    @LogAnnotation(moduleName = "${moduleName}", option = "查询")
	@Override
	public ${className} selectBy${key}(String id) {
		Map<String, Object> map = new HashMap<>();
		map.put("id", id);
		return this.${paramName}Dao.selectBy${key}(map);
	}

	@LogAnnotation(moduleName = "${moduleName}", option = "验证编号唯一")
	@Override
	public StateInfo validator(String key,String value, Bridge bridge) {
		StateInfo stateInfo = new StateInfo();
		try {
			if(!CommonUtil.isEmpty(${paramName}Dao.validator(key,value,bridge))) {
				stateInfo.setFlag(false);
				stateInfo.setMsg(this.getClass(),"已录入重复的${key}编号，请修改！",null);
			}
		}catch(Exception e) {
			stateInfo.setFlag(false);
			stateInfo.setMsg(this.getClass(),e.getMessage(),e);
		}
		return stateInfo;
	}

	@Override
    public int getCount(String keyword,String node,Bridge bridge) {
        Map<String,Object> map = new HashMap<>();
		keyword = CommonUtil.decodeKeyWord(this.getClass(),keyword);
		map.put("keyword", keyword);
		map.put("node", node);
		map.put("year", bridge.getYear());
		map.put("companyid",bridge.getCompanyid());
        Map<String,Object> resultMap = this.${paramName}Dao.getCount(map);
        return Integer.parseInt(CommonUtil.nullToZero(String.valueOf(resultMap.get("count"))));
    }

	@LogAnnotation(moduleName = "${moduleName}", option = "查询列表数据")
	@Override
	public List<${className}> get(String keyword, String node, Bridge bridge, String start, String limit) {
		Map<String,Object> map = new HashMap<>();
		keyword = CommonUtil.decodeKeyWord(this.getClass(),keyword);
		map.put("keyword", keyword);
		map.put("node", node);
		map.put("year", bridge.getYear());
		map.put("companyid",bridge.getCompanyid());
        <#if showWay == 'LIST'>
        map.put("start", start);
		map.put("end", Integer.parseInt(start)+Integer.parseInt(limit));
		return this.${paramName}Dao.getPage(map);
        <#else>
		List<${className}> result = this.${paramName}Dao.get(map);
        </#if>
        <#if leaf??>
		if(CommonUtil.isEmpty(keyword)) {
			for(${className} m : result) {
				m.setId(String.valueOf(m.${getKey}()));
				m.setLeaf(m.${getLeaf}()==1);
			}
		}else {
			for(${className} m : result) {
				m.setId(String.valueOf(m.${getKey}()));
				m.setLeaf(true);
			}
		}
		return result;
        </#if>
	}

    @LogAnnotation(moduleName = "${moduleName}", option = "删除")
	@Override
	public StateInfo delete(String code,String parentId, Bridge bridge) {
		StateInfo stateInfo = new StateInfo();
		if(!CommonUtil.isEmpty(code)) {
			try {
				Map<String,Object> map = new HashMap<>();
				map.put("year", bridge.getYear());
				map.put("id",code);
				//顺序不能乱
                <#if showWay != 'LIST'>
                <#--
				StringBuffer sql = this.treeAutoSum(code,bridge,true);
				-->
				</#if>
				this.${paramName}Dao.deleteByPrimaryKey(map);
				if(!CommonUtil.isEmpty(parentId) && !"0".equals(parentId) && !"root".equals(parentId)) {
					map.put("node",parentId);
					map.put("companyid",bridge.getCompanyid());

                    <#if leaf??>
					List<${className}> childrens = this.${paramName}Dao.get(map);
					//父节点没有子节点要把父节点的leaf 设置为0
					if(childrens == null || childrens.size() == 0) {
						Map<String,Object> map2 = new HashMap<>();
						map2.put("year", bridge.getYear());
						map2.put("id",parentId);
						map2.put("value","1");
						//父节点leaf 设置为0
						this.${paramName}Dao.changeLeaf(map2);
					}
                    </#if>
				}
                <#if showWay != 'LIST'>
                <#--
                comDao.executeSQL(sql.toString());
                -->
                </#if>
			}catch(Exception e){
				stateInfo.setFlag(false);
				stateInfo.setMsg(this.getClass(),e.getMessage(),e);
			}
		}else {
			stateInfo.setFlag(false);
			stateInfo.setMsg(this.getClass(),"传递的id为空无法删除，请刷新后重试！",null);
		}
		return stateInfo;
	}
	/**
	 * 获取bean 信息的map 用于传递给mybatis
	 */
	private Map<String,Object> getBeanInfoMap(${className} ${paramName}, Bridge bridge){
		<#if companyidMethod??>
		${paramName}.${companyidMethod}(bridge.getCompanyid());
		</#if>
		<#if theyearMethod??>
		${paramName}.${theyearMethod}(bridge.getYear());
		</#if>
		<#if themonthMethod??>
		${paramName}.${themonthMethod}(bridge.getMonth());
		</#if>
		
		Map<String,Object> map = new HashMap<>();
		map.put("year", bridge.getYear());
		<#list normalList as bean>
		map.put("${bean.proper}",${paramName}.${bean.getMethod}());
		</#list>
		return map;
	}

    @LogAnnotation(moduleName = "${moduleName}", option = "修改")
	@Override
	public StateInfo edit(String ${key}, ${className} ${paramName}, Bridge bridge) {
		StateInfo stateInfo = new StateInfo();
		if(!CommonUtil.isEmpty(${key}) && ${paramName} != null) {
			Map<String,Object> map = this.getBeanInfoMap(${paramName},bridge);
			map.put("whereId",${key});
			try {
				this.${paramName}Dao.update(map);
				<#if showWay != 'LIST'>
                <#-- StringBuffer sql = this.treeAutoSum(parentId,bridge,true);
			    if(sql.length()>0) {
				    comDao.executeSQL(sql);
                }
                -->
				</#if>
			}catch(Exception e) {
				stateInfo.setFlag(false);
				stateInfo.setMsg(this.getClass(),e.getMessage(),e);
			}
		}else {
			stateInfo.setFlag(false);
			stateInfo.setMsg(this.getClass(),"传递的关键字段为空或者对象不存在，请刷新页面重试",null);
		}
		return stateInfo;
	}

    @LogAnnotation(moduleName = "${moduleName}", option = "新增")
	@Override
	public StateInfo add(String parentId,${className} ${paramName}, Bridge bridge) {
		//tree init
        <#if leaf??>
        ${paramName}.${setLeaf}(1);
        </#if>
        <#if parentId??>
		if(!CommonUtil.isEmpty(parentId)) {
            <#if parentIdType == 'STRING'>
                ${paramName}.${setParentId}(parentId);
            <#elseif parentIdType == 'INT'>
                ${paramName}.${setParentId}(Integer.parseInt(parentId));
            <#else>
                ${paramName}.${setParentId}(Double.parseDouble(parentId));
            </#if>
		}else {
            <#if parentIdType == 'STRING'>
                ${paramName}.${setParentId}(Global.NULLSTRING);
            <#elseif parentIdType == 'INT'>
                ${paramName}.${setParentId}(0);
            <#else>
                ${paramName}.${setParentId}(0);
            </#if>
		}
        </#if>
		<#if autoGeneral??>
		//自动生成主键按1 101 10101规则
		Map<String,Object> mapOfID = this.${paramName}Dao.getAutoGeneralID(parentId,bridge);
		${paramName}.${setKey}(CommonUtil.dealPKRule(mapOfID,parentId));
		</#if>
		Map<String,Object> map = this.getBeanInfoMap(${paramName},bridge);
		StateInfo stateInfo = new StateInfo();
		try {
            <#if leaf??>
			if(!CommonUtil.isEmpty(parentId)) {
				Map<String,Object> map2 = new HashMap<>();
				map2.put("year", bridge.getYear());
				map2.put("id",parentId);
				map2.put("value","0");
				//父节点leaf 设置为0
				this.${paramName}Dao.changeLeaf(map2);
			}
            </#if>
			this.${paramName}Dao.insert(map);
            <#--
			<#if showWay != 'LIST'>
			StringBuffer sql = this.treeAutoSum(parentId,bridge,true);
			if(sql.length()>0) {
				comDao.executeSQL(sql.toString());
			}
			</#if>
			-->
		}catch(Exception e) {
			stateInfo.setFlag(false);
			stateInfo.setMsg(this.getClass(),e.getMessage(),e);
		}
		return stateInfo;
	}
<#if showWay != 'LIST'>
<#--
	/**
	 * 自动汇总数值
	 */
	public StringBuffer treeAutoSum(String ${key},Bridge bridge,boolean flag) {
		StringBuffer sqlBuffer = new StringBuffer();
	<#if treeSums??>
		Map<String,Object> paramMap = new HashMap<>();
		paramMap.put("year", bridge.getYear());
		paramMap.put("hbdwbh",bridge.getCompanyid());
		paramMap.put("dwbh",bridge.getDwbh());
		List<${className}> list = ${paramName}Dao.getAll(bridge.getCompanyid());
		Map<String,String> leaf_parentMap = new HashMap<String,String>();
		for(${className} ${paramName} : list) {
            <#if getParentId??>
			leaf_parentMap.put(String.valueOf(${paramName}.${getKey}()),String.valueOf(${paramName}.${getKey}()));
            <#else>
			leaf_parentMap.put(String.valueOf(${paramName}.${getKey}()),String.valueOf(${paramName}.${getParentId}()));
            </#if>
		}
		String tableName = "${tableNameOriginal}";
		tableName = tableName.toUpperCase().replace("@YEAR",bridge.getYear());
		
		String parentId = leaf_parentMap.get(${key});
		if(flag) {
			parentId = ${key};
		}
		
		String[] ss = new String[]{<#list treeSums as tss>"${tss}"<#sep>,</#list>};
		while(leaf_parentMap != null && !CommonUtil.isEmpty(parentId) && !"0".equals(parentId)) {
		
			sqlBuffer.append("Update ").append(tableName).append(" Set ");
			for(int i=0; i<ss.length; i++) {
				if(i>0) {
					sqlBuffer.append(",");
				}
				sqlBuffer.append(ss[i] + " = ( ");
 				sqlBuffer.append("select SUM(convert(decimal(18,2),"+ss[i]+")) from ").append(tableName).append(" "); 
 				sqlBuffer.append("where parentId = '"+parentId+"'");
				sqlBuffer.append(" ) ");
			}
			
			sqlBuffer.append("Where ${keyDB} = '").append(parentId).append("';");
			parentId = leaf_parentMap.get(parentId);
		}
	</#if>
		return sqlBuffer;
	}
-->
</#if>
	<#if copyLastYearData == true>
	/**
	 *拷贝上年数据
	 */
    @LogAnnotation(moduleName = "${moduleName}", option = "拷贝上年数据")
	@Override
	public StateInfo copyLasyYearData(Bridge bridge){
		StateInfo stateInfo = new StateInfo();
		try{
			this.${paramName}Dao.deleteAll(bridge.getYear());
			this.${paramName}Dao.copyLastYear(String.valueOf(Integer.parseInt(bridge.getYear())-1),bridge.getYear());
		}catch(Exception e){
			stateInfo.setFlag(false);
			stateInfo.setMsg(this.getClass(),e.getMessage(),e);
		}
		return stateInfo;
	}
	</#if>

	<#if autoInitFromAccess == true>
	/**
	 *初始化内置数据
	 */
     @LogAnnotation(moduleName = "${moduleName}", option = "初始化数据")
	 @Override
	 public StateInfo autoInitFromAccess(Bridge bridge){
	 	StateInfo stateInfo = new StateInfo();
	 	Connection conn = null;
	 	Statement stmt = null;
	 	ResultSet rs = null;
	 	try{
			this.${paramName}Dao.deleteAll(bridge.getYear());
			conn = AccessOptUtil.connectAccessFile();
            if(conn != null) {
                stmt = conn.createStatement();
                rs = stmt.executeQuery("Select * From ${tableName}");
                List<String> sqlList = new ArrayList<>();
                StringBuilder sqlBuffer = new StringBuilder();
                while(rs.next()) {
                    sqlBuffer.setLength(0);
            <#if yearTable>
                    sqlBuffer.append("Insert Into ${tableName}").append(bridge.getYear());
            <#else>
                    sqlBuffer.append("Insert Into ${tableName}");
            </#if>
                    sqlBuffer.append("(<#list normalList as normalOne>${normalOne.dbcname}<#sep>,</#list>) values (");
            <#list normalList as normalOne>
                <#if companyidMethod ?? && normalOne.setMethod == companyidMethod>
                    sqlBuffer.append("'").append(bridge.getCompanyid()).append("'");
                <#else>
                    <#if normalOne.type=='VARCHAR'>
                    sqlBuffer.append("'").append(rs.getString("${normalOne.dbcname}")).append("'");
                    <#elseif normalOne.type=='INTEGER'>
                    sqlBuffer.append(rs.getInt("${normalOne.dbcname}"));
                    <#elseif normalOne.type=='DECIMAL'>
                    sqlBuffer.append(rs.getDouble("${normalOne.dbcname}"));
                    </#if>
                </#if>
                <#sep>sqlBuffer.append(",");
            </#list>

                    sqlBuffer.append(")");
                    sqlList.add(sqlBuffer.toString());
                }
                comDao.transactionUpdate(sqlList);
            }
		}catch(Exception e){
			stateInfo.setFlag(false);
			stateInfo.setMsg(this.getClass(),e.getMessage(),e);
		}finally {
			Global.close(conn,stmt,rs);
		}
	 	return stateInfo;
	 }
	</#if>
    <#if importData == true>
    @LogAnnotation(moduleName = "${moduleName}", option = "导入Excel数据")
    @Override
	public StateInfo importData(File targetFile, Bridge bridge) {
		HSSFWorkbook wb = null;
		StateInfo stateInfo = new StateInfo();
		try {
			List<${className}> list = new ArrayList<>();
			wb = new HSSFWorkbook(new FileInputStream(targetFile));
			HSSFSheet sheet = wb.getSheetAt(0);
			int beginIndex = 1; // 数据的起始行
			int rows = sheet.getLastRowNum();
			int j;
			for (int i = beginIndex; i <= rows; i++) {
				j = 0;
                ${className} ${paramName} = new ${className}();
                <#list beans as bean>
                    <#if bean.type == 'STRING'>
                        ${paramName}.${bean.setMethodName}(CommonUtil.getCellValue(sheet.getRow(i).getCell(j++)));
                        if(CommonUtil.isEmpty(${paramName}.${bean.getMethodName})) {
                            stateInfo.setFlag(false);
                            stateInfo.setMsg(this.getClass(),"第"+(i+1)+"行，第"+j+"列，数据为空，请校对编辑后重新上传",null);
                            return stateInfo;
                        }
                    <#elseif bean.type == 'INT'>
                        ${paramName}.${bean.setMethodName}(Integer.parseInt(CommonUtil.getCellValue(sheet.getRow(i).getCell(j++))));
                    <#else>
                        ${paramName}.${bean.setMethodName}(Double.parseDouble(CommonUtil.getCellValue(sheet.getRow(i).getCell(j++))));
                    </#if>

                </#list>
				list.add(${paramName});
			}
            ${paramName}Dao.insert${className}s(list);
		}catch (Exception e) {
			stateInfo.setFlag(false);
			stateInfo.setMsg(this.getClass(),e.getMessage(),e);
		}finally {
			targetFile.delete();
			targetFile.deleteOnExit();
		}
		return stateInfo;
	}

    @LogAnnotation(moduleName = "${moduleName}", option = "导出Excel数据")
    @Override
	public StateInfo exportData(OutputStream os,Bridge bridge) {
		StateInfo stateInfo = new StateInfo();
		String sheetName = "${tableJsName}";   //导出的Excel名称
		String [] headers = {${jsNameStr};
		String [] columns = {${properStr}};
		List<${className}> list = this.get(null,null,bridge,"0","999999999");
		ExportExcelUtil<${className}> util = new ExportExcelUtil<${className}>();
		try {
			util.export(sheetName,headers,columns,list,os);
		} catch (Exception e) {
			stateInfo.setFlag(false);
			stateInfo.setMsg(this.getClass(),e.getMessage(),e);
		}
		return stateInfo;
	}

    @LogAnnotation(moduleName = "${moduleName}", option = "导出Excel模板")
    @Override
	public StateInfo exportExcelTemplate(OutputStream os,Bridge bridge) {
		//TODO 自定义你自己的EXCEL导入模板或者直接让他等于导出数据
		return exportData(os,bridge);
	}
    </#if>
}